package com.cskaoyan.catmall.aspectj;

import com.cskaoyan.catmall.annotation.OperationLog;
import com.cskaoyan.catmall.dao.LogMapper;
import com.cskaoyan.catmall.dao.OperationLogMapper;
import com.cskaoyan.catmall.model.pojo.MarketLog;
import com.cskaoyan.catmall.model.pojo.User;
import com.cskaoyan.catmall.model.pojo.UserPojo;
import com.cskaoyan.catmall.model.vo.BaseRespVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.PrincipalCollection;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 创建日期: 2022-01-12-20-35
 * author : WQW
 * description: 记录管理员的操作日志
 */
@Order(1)
@Aspect
@Component
public class RecordULogAspect {


    @Autowired
    LogMapper logMapper;

    /**
     * @param
     * @param joinPoint
     * @return void
     * @description
     * @author WQW
     * @date 2022/1/12 20:54
     */
    @Around("execution(* com.cskaoyan.catmall.controller.background..*.*(..))")
//    @Around("execution(@annotation("com.cskaoyan.catmall.annotation.OperationLog"))")
    public Object recordULog(ProceedingJoinPoint joinPoint) throws Throwable {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            OperationLog declaredAnnotation = signature.getMethod().getDeclaredAnnotation(OperationLog.class);
            String value = null;
            Integer type = 1;
            if (declaredAnnotation != null) {
                value = declaredAnnotation.value(); // 获取到OperationLog注解中的描述信息
                type = declaredAnnotation.type(); // 获取到OperationLog注解中的操作分类信息
            }
            String remoteAddr = request.getRemoteAddr();// 获取到操作管理员的ip地址
            String username = null;
            if (!request.getRequestURI().contains("login")) {
                PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
                UserPojo admin = (UserPojo) principals.getPrimaryPrincipal();
                username = admin.getUsername();// 获取登录管理员的名称
            } else {
                Object[] args = joinPoint.getArgs();
                for (Object arg : args) {
                    if (arg instanceof Map) {
                        username = (String) ((Map) arg).get("username");
                    }
                }
            }
            BaseRespVo proceed = (BaseRespVo) joinPoint.proceed();
            Boolean status = true;// 定义管理员操作状态
            String message = null;
            if (proceed.getErrno() != 0) {
                status = false;
                message = proceed.getErrmsg();// 获取到管理员操作失败时的错误信息
            }
            // 将日志信息插入数据库
            logMapper.insertLog(new MarketLog(null, username, remoteAddr, type, value, status, message));
        return proceed;
    }


}
